home *** CD-ROM | disk | FTP | other *** search
/ Aminet 28 / Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso / Aminet / util / libs / graphics3d.lha / src / library / graphics3Df_i.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-10-17  |  30.1 KB  |  1,344 lines

  1. /*
  2. **      $VER: graphics3Df_i.c 10.10 (16.02.98)
  3. **
  4. **      Internal functions for graphics3D.library
  5. **
  6. **      (C) Copyright 97 Patrizio Biancalani
  7. **      All Rights Reserved.
  8. **
  9. **    Note: this code is traslate from the blitzbasic 3d graphics engine 
  10. **          V 0.9 of Maciej R. Gorny.
  11. */
  12.  
  13. #include <exec/types.h>
  14. #include <exec/memory.h>
  15. #include <proto/exec.h>
  16. #include <proto/intuition.h>
  17. #include <intuition/intuition.h>
  18. #include <intuition/screens.h>
  19.  
  20. #include <graphics/rastport.h>
  21. #include <graphics/clip.h>
  22. #include <graphics/regions.h>
  23. #include <graphics/gfx.h>
  24. #include <graphics/gfxmacros.h>
  25. #include <graphics/layers.h>
  26.  
  27. #include "graphics3Dc.h"
  28. #include "graphics3D.h"
  29. #include "graphics3d2d.h"
  30. #include "graphics3d2d_proto.h"
  31.  
  32. /** prototipi locali **/
  33. struct objectnode *resetobj(struct ambient3d *in);
  34. struct objectnode *nextobj(struct ambient3d *in);
  35. struct objectnode *pobj(struct ambient3d *in);
  36.  
  37. /*** funzioni esterne solo matematiche ***/
  38. extern void matidentity4x4(struct matrix4x4 *imatrix); 
  39. extern void matzero4x4(struct matrix4x4 imatrix);
  40. extern void matcopy4x4(struct matrix4x4 *s_m,struct matrix4x4 *d_m);
  41. extern void matmult4x4(struct matrix4x4 *a,struct matrix4x4 *b,
  42.         struct matrix4x4 *r);
  43. extern void matmult4x4s(struct matrix4x4 *a,struct matrix4x4 *b,
  44.         struct matrix4x4 *r);
  45. extern void matmult1x4s(struct matrix1x4 *a,struct matrix4x4 *b,
  46.         struct matrix1x4 *r);
  47. extern void makevector3d(struct vertex *a,struct vertex *b,
  48.          struct vector *result);
  49. extern long int vectormag3d(struct vector *a);
  50. extern void normalpol(struct vertex *v0,struct vertex *v1,
  51.      struct vertex *v2,struct vector *normal);
  52. extern long int dotproduct(struct vector *u,struct vector *v);
  53. extern long int sqri(long int v);
  54. extern long int abs(long int val);
  55.  
  56. /************************************/
  57. /* costruzione tavole seno e coseno */
  58. /************************************/
  59. void buildlookuptables(in)
  60. struct ambient3d *in;
  61. {
  62. long int *sn,*cn,i,ii;
  63. long int t[]=
  64. {    
  65. /** val. seno angolo (0,90) e moltiplicato per 256 **/
  66.     0,4,9,13,17,22,26,30,35,39,43,47,52,
  67.     56,60,65,69,73,77,81,85,89,93,98,101,105,
  68.     109,113,117,121,125,129,132,136,140,143,
  69.     147,151,154,157,161,164,167,171,174,177,
  70.     180,183,186,189,192,195,198,200,203,206,
  71.     208,211,213,216,218,220,222,225,227,229,
  72.     230,232,234,236,238,239,241,242,243,245,
  73.     246,247,248,249,250,251,252,253,253,254,
  74.     254,255,255,255,256
  75. };
  76.  
  77. /*
  78. #ifdef DEBUG
  79. char dbg[80];
  80. #endif
  81. */
  82.  
  83. sn=in->sintable;
  84. cn=in->costable;
  85. /** val. seno angolo (0,90) e moltiplicato per 1024 **/
  86. /*
  87. t:=[0,17,35,53,71,89,
  88.     106,124,142,160,177,195,212,230,247,264,282,299,
  89.     316,333,350,366,383,399,416,432,448,464,480,496,
  90.     511,527,542,557,572,587,601,615,630,644,657,671,
  91.     684,698,711,723,736,748,760,772,784,795,806,817,
  92.     828,838,848,858,868,877,886,895,903,912,920,927,
  93.     935,942,949,955,962,968,973,979,984,988,993,997,
  94.     1001,1005,1008,1011,1013,1016,1018,1020,1021,1022,
  95.     1023,1023,1024]:LONG
  96. */
  97. ii=0;
  98. for(i=0; i<361; i++)
  99.     {
  100.     if (i<91)
  101.         {
  102.         sn[i]=t[ii];
  103.         cn[i]=t[90-ii];
  104.         }
  105.     else if (i<181) 
  106.         {
  107.         sn[i]=t[90-ii];
  108.         cn[i]=-t[ii];
  109.         }
  110.     else if (i<271)
  111.         {
  112.         sn[i]=-t[ii];
  113.         cn[i]=-t[90-ii];
  114.         }
  115.     else
  116.         {
  117.         sn[i]=-t[90-ii];
  118.         cn[i]=t[ii];
  119.         }
  120. /*
  121. #ifdef DEBUG
  122. sprintf(dbg,"t[%ld]=%ld sn[%ld]=%ld cn[%ld]=%ld\n",ii,t[ii],i,sn[i],i,cn[i]);
  123. write_dbg(dbg);
  124. #endif
  125. */
  126.     ii++;
  127.     if (ii>90) ii=1;
  128.     }
  129. }
  130.  
  131. /*******************************************************/
  132. /** crea la matrice di trasformazione inversa globale **/
  133. /** usata per passare da coordinate del mondo in      **/
  134. /** coordinate della camera                  **/
  135. /** Crea matrice in.global_view per capirci.          **/
  136. /*******************************************************/
  137. void createworldtocamera(in)
  138. struct ambient3d *in;
  139. {
  140. long int temp,active_axes;
  141. struct matrix4x4 translate,rotate_x,rotate_y,rotate_z;
  142. struct matrix4x4 result_1,result_2,*g_v;
  143. struct vector *v_p;
  144. struct dir3d *v_a;
  145. long int *cos,*sin;
  146.  
  147. cos=in->costable;
  148. sin=in->sintable;
  149. v_a=&in->view_angle;
  150. v_p=&in->view_point;
  151. g_v=&in->global_view;
  152.  
  153. active_axes=0;
  154.  
  155. matidentity4x4(&translate);
  156. translate.r3c0=-v_p->x;
  157. translate.r3c1=-v_p->y;
  158. translate.r3c2=-v_p->z;
  159.  
  160. if (v_a->angx!=NULL AND v_a->angx!=360)
  161.     {
  162.     matidentity4x4(&rotate_x);
  163.     rotate_x.r1c1=cos[v_a->angx];
  164.     rotate_x.r1c2=sin[v_a->angx];
  165.     rotate_x.r2c1=-sin[v_a->angx];
  166.     rotate_x.r2c2=cos[v_a->angx];
  167.     active_axes=active_axes+1;
  168.     }
  169.  
  170. if (v_a->angy!=NULL AND v_a->angy!=360)
  171.     {
  172.     matidentity4x4(&rotate_y);
  173.     rotate_y.r0c0=cos[v_a->angy];
  174.     rotate_y.r0c2=sin[v_a->angy];
  175.     rotate_y.r2c0=-sin[v_a->angy];
  176.     rotate_y.r2c2=cos[v_a->angy];
  177.     active_axes=active_axes+2;
  178.     }
  179.  
  180. if (v_a->angz!=NULL AND v_a->angz!=360)
  181.     {
  182.     matidentity4x4(&rotate_z);
  183.     rotate_z.r0c0=cos[v_a->angz];
  184.     rotate_z.r0c1=-sin[v_a->angz];
  185.     rotate_z.r1c0=sin[v_a->angz];
  186.     rotate_z.r1c1=cos[v_a->angz];
  187.     active_axes=active_axes+4;
  188.     }
  189.  
  190. switch (active_axes)
  191.     {
  192.     case (0):
  193.         matcopy4x4(&translate,g_v);
  194.         break;
  195.  
  196.     case (1):
  197.         matcopy4x4(&rotate_x,g_v);
  198.         g_v->r3c0=-v_p->x;
  199.         temp=-v_p->y*cos[v_a->angy] - v_p->z*sin[v_a->angy];
  200.         g_v->r3c1=temp >> SFIXV;
  201.         temp=v_p->y*sin[v_a->angy] - v_p->z*cos[v_a->angy];
  202.         g_v->r3c2=temp >> SFIXV;
  203.         break;
  204.  
  205.     case (2):
  206.         matcopy4x4(&rotate_y,g_v);
  207.         temp=-v_p->x*cos[v_a->angy]+v_p->z*sin[v_a->angy];
  208.         g_v->r3c0=temp >> SFIXV;
  209.         g_v->r3c1=-v_p->y;
  210.         temp=-v_p->y*sin[v_a->angy]-v_p->z*cos[v_a->angy];
  211.         g_v->r3c2=temp >> SFIXV;
  212.         break;
  213.  
  214.     case (3):
  215.         matmult4x4s(&translate,&rotate_x,&result_1);
  216.         matmult4x4s(&result_1,&rotate_y,g_v);
  217.         break;
  218.  
  219.     case (4):
  220.         matcopy4x4(&rotate_z,g_v);
  221.         temp=-v_p->x*cos[v_a->angz]-v_p->y*sin[v_a->angz];
  222.         g_v->r3c0=temp >> SFIXV;
  223.         temp= v_p->x*sin[v_a->angz]-v_p->y*cos[v_a->angz];
  224.         g_v->r3c1=temp >> SFIXV;
  225.         g_v->r3c3=-v_p->z;
  226.         break;
  227.  
  228.     case (5):
  229.         matmult4x4s(&translate,&rotate_x,&result_1);
  230.         matmult4x4s(&result_1,&rotate_z,g_v);
  231.         break;
  232.  
  233.     case (6):
  234.         matmult4x4s(&translate,&rotate_y,&result_1);
  235.         matmult4x4s(&result_1,&rotate_z,g_v);
  236.         break;
  237.  
  238.     case (7):
  239.         matmult4x4s(&translate,&rotate_x,&result_1);
  240.         matmult4x4s(&result_1,&rotate_y,&result_2);
  241.         matmult4x4s(&result_2,&rotate_z,g_v);
  242.         
  243.     }
  244. }
  245.  
  246. /*****************************************************/
  247. /** determina se l'intero oggetto corrente e' fuori **/
  248. /** dal volume compreso nella visuale o inattivo.   **/
  249. /** Se si rimosso ,ritorna un valore <>0        **/
  250. /*****************************************************/
  251. long int t_removeobject(in)
  252. struct ambient3d *in;
  253. {
  254. long int n_z,f_z;
  255. long int temp,x_bsphere,y_bsphere,z_bsphere;
  256. long int xmax,ymax,zmax,xmin,ymin,zmin,x_compare,y_compare;
  257. struct objectnode *obj;
  258. struct matrix4x4 *g_v;
  259.  
  260. #ifdef DEBUG
  261. char dbg[100];
  262. #endif
  263.  
  264. /* trasformo da interi a fixpoint */
  265. f_z=in->far_z * FIXV;
  266. n_z=in->near_z * FIXV;
  267.  
  268. obj=pobj(in);
  269. g_v=&in->global_view;
  270.  
  271. /* test se oggetto disattivato ,quindi invisibile */
  272. if (!obj->state) return(1);
  273.     
  274. /* segnalo oggetto non clippato per default */
  275. obj->clipped=0;
  276.  
  277. xmax=obj->xmax;
  278. ymax=obj->ymax;
  279. zmax=obj->zmax;
  280. xmin=obj->xmin;
  281. ymin=obj->ymin;
  282. zmin=obj->zmin;
  283.  
  284. temp=obj->worldposx*g_v->r0c0 + obj->worldposy*g_v->r1c0 +
  285.     obj->worldposz*g_v->r2c0;
  286. x_bsphere=(temp>>SFIXV) + g_v->r3c0;
  287. temp=obj->worldposx*g_v->r0c1 + obj->worldposy*g_v->r1c1 +
  288.       obj->worldposz*g_v->r2c1;
  289. y_bsphere=(temp>>SFIXV) + g_v->r3c1;
  290. temp=obj->worldposx*g_v->r0c2 + obj->worldposy*g_v->r1c2 +
  291.       obj->worldposz*g_v->r2c2;
  292. z_bsphere=(temp>>SFIXV) + g_v->r3c2;
  293.  
  294. /*
  295. #ifdef DEBUG
  296. sprintf(dbg,"r0c2=%ld r1c2=%ld r2c2=%ld r3c2=%ld\n",g_v->r0c1,g_v->r1c2,
  297.     g_v->r2c2,g_v->r3c2);
  298. write_dbg(dbg);
  299. sprintf(dbg,"temp=%ld x=%ld y=%ld z=%ld\n",temp,obj->worldposx,
  300.     obj->worldposy,obj->worldposz);
  301. write_dbg(dbg);
  302. sprintf(dbg,"far=%ld near=%ld zmax=%ld zmin=%ld\n",f_z,n_z,zmax,zmin);
  303. write_dbg(dbg);
  304. sprintf(dbg,"xmax=%ld xmin=%ld ymax=%ld ymin=%ld\n",xmax,xmin,ymax,ymin);
  305. write_dbg(dbg);
  306. sprintf(dbg,"x=%ld y=%ld z=%ld\n",x_bsphere,y_bsphere,z_bsphere);
  307. write_dbg(dbg);
  308. sprintf(dbg,"clipmode ZPLANE\n");
  309. if (in->clip_mode!=ZPLANE) sprintf(dbg,"clipmode FRUSTUM\n");
  310. write_dbg(dbg);
  311. #endif
  312. */
  313.  
  314. /* clip con bounding box */
  315. if (in->clip_mode==ZPLANE)
  316.     {
  317.     if (z_bsphere+zmax>f_z OR z_bsphere+zmin<n_z) 
  318.         {
  319.         obj->clipped=1;
  320. /*
  321. #ifdef DEBUG
  322. sprintf(dbg,"oggetto clippato 2\n");
  323. write_dbg(dbg);
  324. #endif
  325. */
  326.         return(2);
  327.         }
  328.     else
  329.         {
  330. /*
  331. #ifdef DEBUG
  332. sprintf(dbg,"oggetto non clippato\n");
  333. write_dbg(dbg);
  334. #endif
  335. */
  336.         return(0);
  337.         }    
  338.     }
  339. else   
  340.     {
  341.     /* esegue un completo test su XYZ */
  342.     if ((z_bsphere+zmax)>f_z OR (z_bsphere+zmin)<n_z)
  343.         {
  344.         obj->clipped=1;
  345. /*
  346. #ifdef DEBUG
  347. sprintf(dbg,"oggetto clippato 3\n");
  348. write_dbg(dbg);
  349. #endif
  350. */
  351.         return(3);
  352.         }
  353.     temp=in->half_screen_width*z_bsphere;
  354.     x_compare=temp/in->viewing_distance;
  355. /*
  356. #ifdef DEBUG
  357. sprintf(dbg,"x_comp=%ld\n",x_compare);
  358. write_dbg(dbg);
  359. #endif
  360. */
  361.     if ((x_bsphere+xmax)>x_compare OR (x_bsphere+xmin)<-x_compare)
  362.         {
  363.         obj->clipped=1;
  364. /*
  365. #ifdef DEBUG
  366. sprintf(dbg,"oggetto clippato 4\n");
  367. write_dbg(dbg);
  368. #endif
  369. */
  370.         return(4);
  371.         }
  372.     temp=(in->half_screen_height*z_bsphere)/in->viewing_distance;
  373.     y_compare=(temp*in->inv_aspect_ratio) >> SFIXV;
  374. /*
  375. #ifdef DEBUG
  376. sprintf(dbg,"temp=%ld iv_a_r=%ld y_comp=%ld\n",temp,in->inv_aspect_ratio,
  377.     y_compare);
  378. write_dbg(dbg);
  379. #endif
  380. */
  381.     if ((y_bsphere+ymax)>y_compare OR (y_bsphere+ymin)<-y_compare)
  382.         {
  383.         obj->clipped=1;
  384. /*
  385. #ifdef DEBUG
  386. sprintf(dbg,"oggetto clippato 5\n");
  387. write_dbg(dbg);
  388. #endif
  389. */
  390.         return(5);
  391.         }
  392.     }
  393. /*
  394. #ifdef DEBUG
  395. sprintf(dbg,"oggetto non clippato\n");
  396. write_dbg(dbg);
  397. #endif
  398. */
  399.  
  400. return(0);
  401. }
  402.  
  403. /*******************************************************
  404.  ** trasla le coordinate locali dell'oggetto corrente **
  405.  ** nelle coordinate del mondo                   **
  406.  *******************************************************
  407.  *** INPUT :                           * 
  408.  * in -> valore > 0 restituito da display3d.           *
  409.  *** OUTPUT:                           *
  410.  * nessuno.                           *
  411.  *******************************************************/
  412. void localtoworld(in)
  413. struct ambient3d *in;
  414. {
  415. struct objectnode *obj;
  416. long int index;
  417. struct vertex *vg,*vl;
  418. struct polygon *pl;
  419. long int wx,wy,wz;
  420.  
  421. obj=pobj(in);
  422. vg=obj->vcamera;
  423. vl=obj->vlocal;
  424. pl=obj->polys;
  425. wx=obj->worldposx;
  426. wy=obj->worldposy;
  427. wz=obj->worldposz;
  428.  
  429. for (index=0; index<obj->numverts; index++)
  430.     {
  431.     vg[index].x=vl[index].x+wx;
  432.     vg[index].y=vl[index].y+wy;
  433.     vg[index].z=vl[index].z+wz;
  434.     }
  435. /* resetta flag di invisibilita' */
  436. for (index=0; index<obj->numpolys; index++)
  437.     {
  438.     pl[index].visible=1;
  439.     pl[index].clipped=0;
  440.     }
  441. }
  442.  
  443. /***************************************************
  444.  ** converte le coordinate nel mondo dell'oggetto **
  445.  ** corrente nelle coordinate della camera        **
  446.  ***************************************************
  447.  *** INPUT :                        * 
  448.  * in -> valore > 0 restituito da display3d.       *
  449.  *** OUTPUT:                       *
  450.  * nessuno.                       *
  451.  ***************************************************/
  452. void worldtocamera(in)
  453. struct ambient3d *in;
  454. {
  455. struct objectnode *obj;
  456. long int index,temp,tempx,tempy,tempz,active_axes;
  457. struct vertex *vc;
  458. struct matrix4x4 gv,*g_v;
  459. struct dir3d *vang;
  460.  
  461. obj=pobj(in);
  462. vc=obj->vcamera;
  463. vang=&in->view_angle;
  464. g_v=&in->global_view;
  465.  
  466. active_axes=0;
  467.  
  468. if (vang->angx!=NULL) active_axes=active_axes+1; 
  469. if (vang->angy!=NULL) active_axes=active_axes+2;
  470. if (vang->angz!=NULL) active_axes=active_axes+4;
  471.  
  472. switch (active_axes)
  473.     {
  474.     case (0):
  475.         for (index=0; index<obj->numverts; index++)
  476.             {    
  477.             vc[index].x=vc[index].x+g_v->r3c0;
  478.             vc[index].y=vc[index].y+g_v->r3c1;
  479.             vc[index].z=vc[index].z+g_v->r3c2;
  480.             }
  481.         break;
  482.     case (1):
  483.         for (index=0; index<obj->numverts; index++)
  484.             {    
  485.             vc[index].x=vc[index].x+g_v->r3c0;
  486.             tempy=vc[index].y*g_v->r1c1+vc[index].z*g_v->r2c1;
  487.             tempz=vc[index].y*g_v->r1c2+vc[index].z*g_v->r2c2;
  488.             vc[index].z=(tempz >> SFIXV)+g_v->r3c2;
  489.             vc[index].y=(tempy >> SFIXV)+g_v->r3c1;
  490.             }
  491.         break;
  492.  
  493.     case (2):
  494.         for (index=0; index<obj->numverts; index++)
  495.             {    
  496.             tempx=vc[index].x*g_v->r0c0+vc[index].z*g_v->r2c0;
  497.             vc[index].y=vc[index].y+g_v->r3c1;
  498.             tempz=vc[index].x*g_v->r0c2+vc[index].z*g_v->r2c2;
  499.             vc[index].z=(tempz >> SFIXV)+g_v->r3c2;
  500.             vc[index].x=(tempx >> SFIXV)+g_v->r3c0;
  501.             }
  502.         break;
  503.  
  504.     case (4):
  505.         for (index=0; index<obj->numverts; index++)
  506.             {    
  507.             tempx=vc[index].x*g_v->r0c0+vc[index].y*g_v->r1c0;
  508.             tempy=vc[index].x*g_v->r0c1+vc[index].y*g_v->r1c1;
  509.             vc[index].y=(tempy >> SFIXV)+g_v->r3c1;
  510.             vc[index].x=(tempx >> SFIXV)+g_v->r3c0;
  511.             vc[index].z=vc[index].z+g_v->r3c2;
  512.             }
  513.         break;
  514.  
  515.     default :
  516.         for (index=0; index<obj->numverts; index++)
  517.             {    
  518.             tempx=vc[index].x*g_v->r0c0+vc[index].y*g_v->r1c0+
  519.                 vc[index].z*g_v->r2c0;
  520.             tempy=vc[index].x*g_v->r0c1+vc[index].y*g_v->r1c1+
  521.                 vc[index].z*g_v->r2c1;        
  522.             tempz=vc[index].x*g_v->r0c2+vc[index].y*g_v->r1c2+
  523.                 vc[index].z*g_v->r2c2;        
  524.             vc[index].x=(tempx >> SFIXV)+g_v->r3c0;
  525.             vc[index].y=(tempy >> SFIXV)+g_v->r3c1;
  526.             vc[index].z=(tempz >> SFIXV)+g_v->r3c2;
  527.             }
  528.     }    
  529. }
  530.  
  531. /******************************************************/
  532. /** rimuove le facce posteriori dell'oggetto corrente**/
  533. /** e calcola il flat shading dell'oggetto           **/
  534. /******************************************************/
  535. void removebackfacesandshade(in)
  536. struct ambient3d *in;
  537. {
  538. struct objectnode *obj;
  539. struct vector *vp, *ls;
  540. struct vertex *v0,*v1,*v2;
  541. struct polygon *pol;
  542. long int x,ms1,ms,al,sha_org,shading,curr_poly,dp,intensity;
  543. struct vector u,v;
  544. struct vector normal,norm,sight;
  545. long int norml;
  546.  
  547. vp=&in->view_point;
  548. ls=&in->light_source;
  549. obj=pobj(in);
  550. shading=obj->shade;
  551. sha_org=shading;
  552.  
  553. x=ls->x;
  554.  
  555. ms=in->maxintensity;
  556. ms1=ms << SFIXV;
  557. al=in->ambient_light >> SFIXV;
  558. for (curr_poly=0; curr_poly<obj->numpolys; curr_poly++)
  559.    {
  560.    shading=sha_org;
  561.    pol=&obj->polys[curr_poly];       
  562.    if (pol->twosided==NULL AND pol->numpoints>2)
  563.     {
  564.     v0=&obj->vcamera[pol->vertexlist0];
  565.     v1=&obj->vcamera[pol->vertexlist1];
  566.     v2=&obj->vcamera[pol->vertexlist2];
  567.         
  568.     normalpol(v0,v1,v2,&normal);
  569.     
  570.     sight.x=vp->x - v0->x;
  571.     sight.y=vp->y - v0->y;
  572.     sight.z=vp->z - v0->z;
  573.  
  574.     dp=dotproduct(&normal,&sight);
  575.     if (dp>=NULL)
  576. /* poligono ad una faccia */
  577.        {
  578.        pol->visible=1;
  579.        switch(shading)
  580.          {
  581.          case(FLAT):
  582.     /* calcolo lunghezza normale poligono */
  583.           dp=dotproduct(&normal,ls);
  584.           if (dp>NULL)
  585.          {
  586.                v0=&obj->vlocal[pol->vertexlist0];
  587.              v1=&obj->vlocal[pol->vertexlist1];
  588.                v2=&obj->vlocal[pol->vertexlist2];
  589.                normalpol(v0,v1,v2,&normal);
  590.  
  591.                norml=vectormag3d(&normal);
  592.                if (norml==NULL) norml=FIXV;
  593.              intensity=al+(ms1*dp)/norml;
  594.          if (intensity>ms) intensity=ms;
  595.        /* intensity e' compreso ora tra 0 e ms ,si usera' questo valore */
  596.        /* per trovare l'indice di sfumatura */
  597.          pol->shade=pol->color+intensity;
  598.          }
  599.           else
  600.          {
  601.              pol->shade=pol->color+al;    
  602.              }
  603.           break;
  604.  
  605.          case(SOLID):
  606.            pol->shade=pol->color + (ms>>1);
  607.           break;
  608.  
  609.          default:
  610.     /* se tipo di shading <> da flat si assume solid */
  611.            pol->shade=pol->color;
  612.          }
  613.        }
  614.     else
  615.        {
  616.        pol->visible=0;           
  617.        }
  618.     }
  619.    else if (pol->numpoints>2)
  620.     {
  621. /* poligono a due facce */
  622.     pol->visible=1;
  623.     if (pol->numpoints<3) shading=SOLID; 
  624.     switch (shading)
  625.      {
  626.      case(FLAT):
  627.        v0=&obj->vcamera[pol->vertexlist0];
  628.        v1=&obj->vcamera[pol->vertexlist1];
  629.        v2=&obj->vcamera[pol->vertexlist2];
  630.         
  631.        normalpol(v0,v1,v2,&normal);
  632.     
  633.        dp=dotproduct(&normal,ls);
  634.        if (dp>NULL)
  635.           {
  636.     /* calcolo lunghezza normale poligono */
  637.           v0=&obj->vlocal[pol->vertexlist0];
  638.           v1=&obj->vlocal[pol->vertexlist1];
  639.           v2=&obj->vlocal[pol->vertexlist2];
  640.           normalpol(v0,v1,v2,&normal);
  641.  
  642.           norml=vectormag3d(&normal);
  643.           if (norml==NULL) norml=FIXV;
  644.           intensity=al+(ms1*dp)/norml;
  645.           if (intensity>ms) intensity=ms;
  646.           pol->shade=pol->color+intensity;
  647.           }
  648.        else
  649.           {
  650.           pol->shade=pol->color+al;
  651.           }
  652.        break;
  653.  
  654.      case(SOLID):    
  655.        pol->shade=pol->color + (ms>>1) ;
  656.        break;
  657.  
  658.      default:
  659.     /* se tipo di shading <> da flat si assume solid */
  660.         pol->shade=pol->color ;
  661.      }    
  662.     }
  663.     else
  664.     {
  665.     pol->visible=1;
  666.     pol->shade=pol->color + (ms>>1) ;
  667.     }
  668.    }
  669.  
  670. }
  671.  
  672. /****************************************************/
  673. /** clippa le coordinate della camera dell'oggetto **/
  674. /** corrente rispetto al volume della visuale      **/
  675. /****************************************************/
  676. void clipobject3d(in)
  677. struct ambient3d *in;
  678. {
  679. long int n_z, f_z, curr_poly;
  680. long int x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4;
  681. long int x1_cmp, y1_cmp, x2_cmp, y2_cmp, x3_cmp, y3_cmp, x4_cmp, y4_cmp;
  682. long int vert0, vert1, vert2, vert3, fov_width, fov_height;
  683. struct objectnode *obj;
  684. struct vertex *vc;
  685. struct polygon *pol;
  686.  
  687. obj=pobj(in);
  688.  
  689. vc=obj->vcamera;
  690. pol=obj->polys;
  691.  
  692. /* converto in fixpoint */
  693. n_z=in->near_z*FIXV;
  694. f_z=in->far_z*FIXV;
  695.  
  696. if (in->clip_mode==ZPLANE)
  697.     {
  698. /* cerca di clippare ogni poligono con il volume della visuale */
  699.     for (curr_poly=0 ;curr_poly<obj->numpolys ;curr_poly++)
  700.         {
  701.     /* test di quanti lati */ 
  702.         switch(pol[curr_poly].numpoints)
  703.             {
  704.             case(1):
  705.                 z1=vc[pol[curr_poly].vertexlist0].z;
  706.                 z2=z1;
  707.                 z3=z1;
  708.                 z4=z4;
  709.                 break;
  710.  
  711.             case(2):
  712.                 z1=vc[pol[curr_poly].vertexlist0].z;
  713.                 z2=vc[pol[curr_poly].vertexlist1].z;
  714.                 z3=z2;
  715.                 z4=z2;
  716.                 break;
  717.  
  718.             case(3):
  719.                 z1=vc[pol[curr_poly].vertexlist0].z;
  720.                 z2=vc[pol[curr_poly].vertexlist1].z;
  721.                 z3=vc[pol[curr_poly].vertexlist2].z;
  722.                 z4=z3;
  723.                 break;
  724.  
  725.             case(4):
  726.                 z1=vc[pol[curr_poly].vertexlist0].z;
  727.                 z2=vc[pol[curr_poly].vertexlist1].z;
  728.                 z3=vc[pol[curr_poly].vertexlist2].z;
  729.                 z4=vc[pol[curr_poly].vertexlist3].z;
  730.                 break;
  731.             }
  732.  
  733.         if ((z1<n_z AND z2<n_z AND z3<n_z AND z4<n_z) OR
  734.            (z1>f_z AND z2>f_z AND z3>f_z AND z4>f_z))
  735.             pol[curr_poly].clipped=1;
  736.         }
  737.     }
  738. else
  739.     {
  740. /* FRUSTUM MODE CLIP */
  741.     /* calcolo i campi visivi in fixpoint */
  742.     fov_width=(in->half_screen_width*FIXV)/in->viewing_distance;
  743.     fov_height=((in->half_screen_height*in->inv_aspect_ratio) / 
  744.             in->viewing_distance);
  745.     for (curr_poly=0 ;curr_poly<obj->numpolys ;curr_poly++)        
  746.         {
  747.  
  748.     /* test di quanti lati */
  749.         switch(pol[curr_poly].numpoints)
  750.             {
  751.             case(1):
  752.                 vert0=pol[curr_poly].vertexlist0;
  753.                 x1=vc[vert0].x;
  754.                 y1=vc[vert0].y;
  755.                 z1=vc[vert0].z;
  756.                 x2=x1;
  757.                 y2=y1;
  758.                 z2=z1;
  759.                 x3=x1;
  760.                 y3=y1;
  761.                 z3=z1;
  762.                 x4=x1;
  763.                 y4=y1;
  764.                 z4=z1;
  765.                 break;
  766.             case(2):
  767.                 vert0=pol[curr_poly].vertexlist0;
  768.                 vert1=pol[curr_poly].vertexlist1;
  769.                 x1=vc[vert0].x;
  770.                 y1=vc[vert0].y;
  771.                 z1=vc[vert0].z;
  772.                 x2=vc[vert1].x;
  773.                 y2=vc[vert1].y;
  774.                 z2=vc[vert1].z;
  775.                 x3=x2;
  776.                 y3=y2;
  777.                 z3=z2;
  778.                 x4=x2;
  779.                 y4=y2;
  780.                 z4=z2;
  781.                 break;
  782.             case(3):
  783.                 vert0=pol[curr_poly].vertexlist0;
  784.                 vert1=pol[curr_poly].vertexlist1;
  785.                 vert2=pol[curr_poly].vertexlist2;    
  786.                 x1=vc[vert0].x;
  787.                 y1=vc[vert0].y;
  788.                 z1=vc[vert0].z;
  789.                 x2=vc[vert1].x;
  790.                 y2=vc[vert1].y;
  791.                 z2=vc[vert1].z;
  792.                 x3=vc[vert2].x;
  793.                 y3=vc[vert2].y;
  794.                 z3=vc[vert2].z;
  795.                 x4=x3;
  796.                 y4=y3;
  797.                 z4=z3;
  798.                 break;
  799.             case(4):
  800.                 vert0=pol[curr_poly].vertexlist0;
  801.                 vert1=pol[curr_poly].vertexlist1;
  802.                 vert2=pol[curr_poly].vertexlist2;    
  803.                 vert3=pol[curr_poly].vertexlist3;
  804.                 x1=vc[vert0].x;
  805.                 y1=vc[vert0].y;
  806.                 z1=vc[vert0].z;
  807.                 x2=vc[vert1].x;
  808.                 y2=vc[vert1].y;
  809.                 z2=vc[vert1].z;
  810.                 x3=vc[vert2].x;
  811.                 y3=vc[vert2].y;
  812.                 z3=vc[vert2].z;
  813.                 x4=vc[vert3].x;
  814.                 y4=vc[vert3].y;
  815.                 z4=vc[vert3].z;
  816.                 break;
  817.             }
  818.         if (z1<n_z AND z2<n_z AND z3<n_z AND z4<n_z) 
  819.             {
  820.             pol[curr_poly].clipped=1;
  821.             continue;
  822.             }
  823.         if (z1>f_z AND z2>f_z AND z3>f_z AND z4>f_z)
  824.             {
  825.             pol[curr_poly].clipped=1;
  826.             continue;
  827.             }
  828.  
  829.         x1_cmp=(fov_width*z1) >> SFIXV;
  830.         x2_cmp=(fov_width*z2) >> SFIXV;
  831.         x3_cmp=(fov_width*z3) >> SFIXV;
  832.         x4_cmp=(fov_width*z4) >> SFIXV;
  833.  
  834.         if (!((x1>-x1_cmp OR x2>-x2_cmp OR x3>-x3_cmp OR x4>-x4_cmp)
  835.            AND (x1<x1_cmp OR x2<x2_cmp OR x3<x3_cmp OR x4<x4_cmp)))
  836.             {
  837.             pol[curr_poly].clipped=1;
  838.             continue;
  839.             }
  840.         y1_cmp=(fov_height*z1) >> SFIXV;
  841.         y2_cmp=(fov_height*z2) >> SFIXV;
  842.         y3_cmp=(fov_height*z3) >> SFIXV;
  843.         y4_cmp=(fov_height*z4) >> SFIXV;
  844.  
  845.         if (!((y1>-y1_cmp OR y2>-y2_cmp OR y3>-y3_cmp OR y4>-y4_cmp)
  846.            AND (y1<y1_cmp OR y2<y2_cmp OR y3<y3_cmp OR y4<y4_cmp)))
  847.             {
  848.             pol[curr_poly].clipped=1;
  849.             continue;
  850.             }
  851.         }
  852.     }
  853. }    
  854.  
  855. /******************************************************/
  856. /** crea la lista di tutti i poligoni visibili nella **/
  857. /** frame corrente e li memorizza gia' proiettati    **/
  858. /** e' gia' stato ottimizzato il piu' possibile.     **/
  859. /** Ora si calcola la distanza tra il punto medio del**/
  860. /** poligono e l'osservatore per il succ. riordino.  **/
  861. /******************************************************/
  862. void generatepolylist(in)
  863. struct ambient3d *in;
  864. {
  865. long int *iwp;
  866. long int zx,zy,zxp,zyp,id,fix1,fix,curr_poly,i,ii,mz,mx,my,x,y,z;
  867. struct pixel *pt;
  868. struct objectnode *obj;
  869. struct vertex *vc;
  870. struct polygon *pol;
  871. struct polytemp *wpl;
  872.  
  873. #ifdef DEBUG
  874. char dbg[100];
  875. #endif
  876.  
  877. iwp=in->iwpolys;
  878. pt=(struct pixel *)in->temp;
  879.  
  880. #ifdef DEBUG
  881. sprintf(dbg,"pt=%ld\n",pt);
  882. write_dbg(dbg);
  883. #endif
  884.  
  885. obj=resetobj(in);
  886. id=0;
  887. curr_poly=0;
  888. fix=(in->aspect_ratio*in->viewing_distance) >> SFIXV;
  889. fix1=in->aspect_ratio;
  890. zy=(fix*in->zoom) >> SFIXV;
  891. zx=(in->viewing_distance*in->zoom) >> SFIXV;
  892. zxp=in->zoom;
  893. zyp=(in->aspect_ratio*in->zoom) >> SFIXV;
  894.  
  895. /*
  896. #ifdef DEBUG
  897. sprintf(dbg,"\n--- ciclo generatepolylist ---\n");
  898. write_dbg(dbg);
  899. sprintf(dbg,"view distance=%ld fix=%ld\n",in->viewing_distance,fix);
  900. write_dbg(dbg);
  901. #endif
  902. */
  903.  
  904. do 
  905.    {    
  906.    if (obj->clipped==0 AND obj->state!=0) 
  907.     {
  908.     /** proietto tutti i punti dell'oggetto corrente **/
  909.     switch(in->projection_type)
  910.         {
  911.         case(PROSP_P) :
  912.     /* uso proiezione prospettica */
  913.             for(i=0 ;i<obj->numverts ;i++ ) 
  914.                 {
  915.                 vc=&obj->vcamera[i];
  916.                 z=vc->z;
  917.                 if (z==NULL) z=FIXV;    
  918.                 pt[i].x=in->half_screen_width +
  919.                      (vc->x*zx)/z;
  920.                 pt[i].y=in->half_screen_height -
  921.                      (vc->y*zy)/z;
  922.  
  923. /*
  924. #ifdef DEBUG
  925. sprintf(dbg,"vertice #%ld\nxp=%ld yp=%ld \n",i,pt[i].x,pt[i].y);
  926. write_dbg(dbg);
  927. sprintf(dbg,"x=%ld y=%ld z=%ld\n",vc->x,vc->y,z);
  928. write_dbg(dbg);
  929. #endif
  930. */
  931.         
  932.                 }
  933.                 break;
  934.         case(PARAL_P) :
  935.     /* uso proiezione parallela */
  936.             for(i=0 ;i<obj->numverts ;i++ ) 
  937.                 {
  938.                 vc=&obj->vcamera[i];
  939.                 pt[i].x=in->half_screen_width + 
  940.                     ((vc->x*zxp) >> (2*SFIXV));
  941.                 pt[i].y=in->half_screen_height + 
  942.                     ((vc->y*zyp) >> (2*SFIXV));
  943.                 }
  944.                 break;
  945.         }
  946.     /* genero lista di poligoni gia' proiettati */
  947.     vc=obj->vcamera;
  948.     for(curr_poly=0 ;curr_poly<obj->numpolys ;curr_poly++) 
  949.         {
  950.         pol=&obj->polys[curr_poly];
  951.         if (pol->visible!=NULL AND pol->clipped==NULL)
  952.             {
  953.     /* reinizializzo puntatore a indice su lista poligoni */
  954.     /* per velocizzare il successivo riordino          */
  955.             wpl=&in->worldpolys[id];
  956.             iwp[id++]=(long int )wpl;
  957.             mx=0;
  958.             my=0;
  959.             mz=0;
  960.             wpl->numpoints=pol->numpoints;
  961.             wpl->shade=pol->shade;
  962.             wpl->vmode=obj->shade;        
  963.             wpl->obj=obj->id;    
  964.             wpl->npol=curr_poly;
  965.         
  966.             i=pol->vertexlist0;
  967.             wpl->x1=pt[i].x;
  968.             wpl->y1=pt[i].y;
  969.             mx=mx+vc[i].x;
  970.             my=my+vc[i].y;
  971.             mz=mz+vc[i].z;
  972.             
  973.             if (pol->numpoints>=2)            
  974.                 {
  975.                 i=pol->vertexlist1;
  976.                 wpl->x2=pt[i].x;
  977.                 wpl->y2=pt[i].y;
  978.                 mx=mx+vc[i].x;
  979.                 my=my+vc[i].y;
  980.                 mz=mz+vc[i].z;
  981.                 }
  982.  
  983.             if (pol->numpoints>=3)        
  984.                 {
  985.                 i=pol->vertexlist2;
  986.                 wpl->x3=pt[i].x;
  987.                 wpl->y3=pt[i].y;
  988.                 mx=mx+vc[i].x;
  989.                 my=my+vc[i].y;
  990.                 mz=mz+vc[i].z;
  991.             
  992.                 wpl->x4=wpl->x1;
  993.                 wpl->y4=wpl->y1;    
  994.                 }
  995.  
  996.             if (pol->numpoints==4) 
  997.                 {
  998.                 i=pol->vertexlist3;
  999.                 wpl->x4=pt[i].x;
  1000.                 wpl->y4=pt[i].y;
  1001.                 mx=mx+vc[i].x;
  1002.                 my=my+vc[i].y;
  1003.                 mz=mz+vc[i].z;
  1004.  
  1005.                 wpl->x5=wpl->x1;
  1006.                 wpl->y5=wpl->y1;
  1007.                 }
  1008. /* calcolo ora il punto medio */    
  1009.             ii=pol->numpoints << SFIXV;
  1010.             mx=mx/ii ;
  1011.             my=my/ii ;
  1012.             mz=mz/ii ;
  1013. /* 
  1014.    ora calcolo la distanza, considerando che l'osservatore ora 
  1015.    e' nell'origine
  1016.    (non calcolo la radice quadrata, poiche' altrimenti aumento l'errore
  1017.     e il tempo di calcolo).
  1018. */
  1019.  
  1020.             wpl->svalue=mx*mx + my*my + mz*mz;
  1021. /*
  1022. #ifdef DEBUG
  1023. sprintf(dbg,"dist=%ld\n",wpl->svalue);
  1024. write_dbg(dbg);
  1025. #endif
  1026. */
  1027.             }
  1028.         }
  1029.     }
  1030.    obj=nextobj(in);
  1031.    }while(obj!=NULL);
  1032.  
  1033. in->total_polys=id;
  1034.  
  1035. /********************/
  1036. }
  1037.  
  1038. /**********************************************
  1039.  ** riporto oggetto attuale sul primo e      **
  1040.  ** resituisco puntatore a oggetto.          **
  1041.  **********************************************
  1042.  *** INPUT :                      * 
  1043.  * in -> valore > 0 restituito da display3d.  *
  1044.  *** OUTPUT:                      *
  1045.  * puntatore a struttura 1# oggetto.          *
  1046.  **********************************************/
  1047. struct objectnode *resetobj(in)
  1048. struct ambient3d *in;
  1049. {
  1050.  
  1051. in->attuale=0;
  1052.  
  1053. return (pobj(in));
  1054. }
  1055.  
  1056. /**********************************************
  1057.  ** sposto oggetto attuale su prossimo se    **
  1058.  ** finiti restituisco 0 altrimenti puntore  **
  1059.  ** a oggetto.                     **
  1060.  **********************************************
  1061.  *** INPUT :                      * 
  1062.  * in -> valore > 0 restituito da display3d.  *
  1063.  *** OUTPUT:                      *
  1064.  * >0 - puntatore a oggetto successivo.       *
  1065.  * =0 - oggetti finiti.                  *
  1066.  **********************************************/
  1067. struct objectnode *nextobj(in)
  1068. struct ambient3d *in;
  1069. {
  1070.  
  1071. if (in->attuale==in->total_objects-1) return(0); 
  1072.  
  1073. in->attuale=in->attuale+1;
  1074.  
  1075. return (pobj(in));
  1076.  
  1077. /*******************************************
  1078.  ** restituisce indirizzo oggetto attuale **
  1079.  *******************************************/
  1080.  
  1081. struct objectnode *pobj(in)
  1082. struct ambient3d *in;
  1083. {
  1084.  
  1085. return(&in->objects[in->attuale]);
  1086.  
  1087. }
  1088.  
  1089. /************************************************
  1090.  ** aggiorna tutti i valori precalcolati sul   **
  1091.  ** oggetto corrente.                     **
  1092.  ************************************************
  1093.  *** INPUT :                        * 
  1094.  * in -> valore > 0 restituito da display3d.    *
  1095.  *** OUTPUT:                    *
  1096.  * nessuno.                    *
  1097.  ************************************************/
  1098. void aggobj(in)
  1099. struct ambient3d *in;
  1100. {
  1101.  
  1102. computeobjectbox(in);
  1103.  
  1104. }
  1105.  
  1106. /**********************************************/
  1107. /** calcola il bounding box dell'oggetto at- **/
  1108. /** tuale per il controllo delle collisioni  **/
  1109. /**********************************************/
  1110. void computeobjectbox(in)
  1111. struct ambient3d *in;
  1112. {
  1113. struct objectnode *ob;
  1114. struct vertex *vt;
  1115. long int xmax,ymax,zmax,xmin,ymin,zmin;
  1116. long int x,y,z,i;
  1117.  
  1118. ob=pobj(in);
  1119.  
  1120. vt=ob->vlocal;
  1121.  
  1122. xmax=vt[0].x;
  1123. ymax=vt[0].y;
  1124. zmax=vt[0].z;
  1125. xmin=vt[0].x;
  1126. ymin=vt[0].y;
  1127. zmin=vt[0].z;
  1128.  
  1129. for(i=1 ;i<ob->numverts ; i++)
  1130.     {
  1131.     x=vt[i].x;
  1132.     y=vt[i].y;
  1133.     z=vt[i].z;
  1134.     if (x>xmax) xmax=x;
  1135.     if (x<xmin) xmin=x;
  1136.     if (y>ymax) ymax=y;
  1137.     if (y<ymin) ymin=y;
  1138.     if (z>zmax) zmax=z;
  1139.     if (z<zmin) zmin=z;
  1140.     }
  1141.  
  1142. ob->xmax=xmax;
  1143. ob->ymax=ymax;
  1144. ob->zmax=zmax;
  1145. ob->xmin=xmin;
  1146. ob->ymin=ymin;
  1147. ob->zmin=zmin;
  1148.  
  1149. }
  1150.  
  1151. /************************************
  1152.  ** routin richiamata da quicksort **
  1153.  ** occhio e' recursiva.       **
  1154.  ** I parametri non possono percio'**
  1155.  ** essere passati tramite registri**
  1156.  ************************************/
  1157. void qsort(lo0,hi0,pol,count)
  1158. long int lo0;
  1159. long int hi0;
  1160. long int *pol;
  1161. long int *count;
  1162. {
  1163. long int it, lo, hi, mid, t;
  1164. struct polytemp *wpl;
  1165.  
  1166. lo=lo0;
  1167. hi=hi0;
  1168. it=count[0];
  1169.  
  1170. if (hi0>lo0)
  1171. /* stabilisco arbitrariamente il pivot point nel mezzo dell'array */
  1172.     {
  1173.     wpl=(struct polytemp *)pol[(lo0+hi0)>>1];
  1174.     mid=wpl->svalue;
  1175.  
  1176. /* eseguo il loop finche non incrocio indici */
  1177.     while(lo<=hi)
  1178. /* trovo il primo elemento minore o uguale a mid partendo da sinistra */
  1179.         {
  1180.         wpl=(struct polytemp *)pol[lo];
  1181.         while(lo<hi0 AND wpl->svalue>mid)
  1182.             {
  1183.             lo++;
  1184.             wpl=(struct polytemp *)pol[lo];
  1185.             it++;
  1186.             }
  1187. /* trovo il primo elemento maggiore o uguale a mid partendo da destra */
  1188.         wpl=(struct polytemp *)pol[hi];
  1189.         while(hi>lo0 AND wpl->svalue<mid)
  1190.             {    
  1191.             hi--;
  1192.             wpl=(struct polytemp *)pol[hi];
  1193.             it++;
  1194.             }
  1195. /* se gli indici non si sono incrociati scambio elementi */
  1196.         if (lo<=hi)
  1197.             {
  1198.             t=pol[hi];
  1199.             pol[hi]=pol[lo];
  1200.             pol[lo]=t;
  1201.             lo++;
  1202.             hi--;
  1203.             }
  1204.         }
  1205.     }        
  1206.  
  1207. count[0]=it;
  1208.  
  1209. if (lo0<hi) qsort(lo0,hi,pol,count);
  1210.  
  1211. if (lo<hi0) qsort(lo,hi0,pol,count);
  1212.  
  1213. }
  1214.  
  1215. /******************************************************
  1216.  ** visualizza un gruppo di poligoni nella rastport  **
  1217.  ** corrente(purche di 3 o 4 lati).              **    
  1218.  ** E' ottimizzata il piu' possibile.             **
  1219.  ******************************************************
  1220.  **** INPUT :                         ** 
  1221.  **  amb ->valore non 0 ritornato da GD_display3d(). **
  1222.  **  iwp  ->puntatore ad array di puntatori a strut- **
  1223.  **         ture polytemp.                 ** 
  1224.  **  total_polys ->n# totale elementi nell'array iwp **
  1225.  **  colb ->se >=0 allora poligoni con bordo di quel **
  1226.  **         colore.                     **
  1227.  **** OUTPUT:                         **
  1228.  ** nessuno.                         **
  1229.  ******************************************************/
  1230. void paintpol(amb,iwp,total_polys,colb)
  1231. struct ambient3d *amb;
  1232. long int *iwp;
  1233. long int total_polys;
  1234. long int colb;
  1235. {
  1236. struct grafica *graf;
  1237. struct RastPort *rast;
  1238. struct polytemp *wpl;
  1239. long int i,f,f1;
  1240. long int ob,m1,mx;
  1241. short int *pvert;
  1242.  
  1243. #ifdef DEBUG
  1244. char dbg[100];
  1245. #endif
  1246.  
  1247. graf=amb->graf;
  1248.  
  1249. rast=graf->rast;
  1250. mx=graf->lb_af;
  1251.  
  1252. #ifdef DEBUG
  1253. sprintf(dbg,"ambient3d=%ld rast=%ld\n",amb,rast);
  1254. write_dbg(dbg);
  1255. #endif
  1256.  
  1257. f1=((struct polytemp *)iwp[0])->shade;
  1258. SetAPen(rast,f1);
  1259. m1=NULL;
  1260. ob=((struct polytemp *)iwp[0])->obj;
  1261. for (i=0;i<total_polys;i++)
  1262.     {
  1263.     wpl=(struct polytemp *)iwp[i];
  1264.     pvert=(short int *)wpl;
  1265.     /* visualizzo il poligono */ 
  1266. /** visualizza un poligono proiettato **/
  1267.     f=wpl->shade;
  1268.     if (f1!=f)
  1269.         {
  1270. /*
  1271.         SetAPen(rast,f);
  1272. */
  1273.         f1=f;
  1274.         }    
  1275.     switch(wpl->numpoints)
  1276.         {
  1277.         case (1) :
  1278.     /* 1 vertice -> disegno un punto */
  1279.             pixel(amb,pvert[0],pvert[1],f);
  1280.             break;
  1281.         case (2) :
  1282.     /* 2 vertici -> disegno una linea */
  1283.             line(amb,pvert[0],pvert[1],pvert[2],pvert[3],f);
  1284.             break;
  1285.         case (3) :
  1286.     /* 3 vertici -> poligono triangolare disegno in base a wpl->vmode */
  1287.             if (wpl->vmode!=WIREF) 
  1288.                 {
  1289.                 drw_t(amb,pvert,f1,colb);
  1290.                 }
  1291.             else
  1292.                 {
  1293.                 line(amb,pvert[0],pvert[1],pvert[2],pvert[3],f1);
  1294.                 line(amb,pvert[2],pvert[3],pvert[4],pvert[5],f1);
  1295.                 line(amb,pvert[4],pvert[5],pvert[0],pvert[1],f1);
  1296.                 }
  1297.             break;
  1298.         case (4) :
  1299.     /* 4 vertici -> poligono quadrangolare disegno in base a wpl->vmode*/
  1300.             if (wpl->vmode!=WIREF) 
  1301.                 {
  1302.                 drw_q(amb,pvert,f1,colb);
  1303.                 }
  1304.             else
  1305.                 {
  1306.                 line(amb,pvert[0],pvert[1],pvert[2],pvert[3],f1);
  1307.                 line(amb,pvert[2],pvert[3],pvert[4],pvert[5],f1);
  1308.                 line(amb,pvert[4],pvert[5],pvert[6],pvert[7],f1);
  1309.                 line(amb,pvert[6],pvert[7],pvert[0],pvert[1],f1);
  1310.                 }
  1311.             break;
  1312.         }
  1313.     }
  1314.  
  1315. }
  1316.  
  1317. /**********************************************
  1318.  ** effettuo ordinamento poligoni proiettati **
  1319.  ** via quicksort                 **
  1320.  ** mediamente 4 volte piu' veloce dello     ** 
  1321.  ** shellsort.                     **
  1322.  **********************************************
  1323.  **** INPUT :                     **
  1324.  ** len -> numero di poligoni da riordinare  **
  1325.  ** pol -> array di puntatori alle strutture **
  1326.  **        polytemp, da riordinare.          **
  1327.  **** OUTPUT:                     **
  1328.  ** n# di passi effettuati per l'ordinamento.** 
  1329.  **********************************************/
  1330. long int quicksort(len,pol)
  1331. long int len;
  1332. long int *pol;
  1333. {
  1334. long int itera;
  1335.  
  1336. itera=0;
  1337.  
  1338. if (len>NULL) qsort(0,len-1,pol,&itera);
  1339.  
  1340. return(itera);
  1341. }
  1342. /*******************************************************************/
  1343.